home *** CD-ROM | disk | FTP | other *** search
- Path: news.dx.net!NewsWatcher!user
- From: mikedorman@cedarnet.com (Mike Dorman)
- Newsgroups: comp.lang.c
- Subject: help debugging ISR function
- Date: Tue, 02 Jan 1996 16:48:00 -0500
- Organization: CedarNet Online
- Message-ID: <mikedorman-0201961648020001@205.148.200.151>
- NNTP-Posting-Host: 205.148.200.151
-
- This is an ISR function for interrupts 0xB and 0xC (the serial port
- interrupts). And for some reason, whenever it is called, it locks the
- computer. I have no idea why. Please take a look at my code and see if
- you get any ideas. Thanks!
-
- (BTW, this code *doesn't* use UART FIFOs!)
- ========================== begin ISR.INC ======================
- ISR_PROLOG macro
- push ax ; save all registers
- push bx
- push cx
- push dx
- push es
- push ds
- push si
- push di
- push bp
- mov bp,DGRP ; DS data segment
- mov ds,bp
- mov bp,sp ; set up stack frame for locals
- endm
- ISR_EPILOG macro
- ; restore all registers
- pop bp
- pop di
- pop si
- pop ds
- pop es
- pop dx
- pop cx
- pop bx
- pop ax
- iret ; return =
- endm
- ============================ end ISR.INC ==========================
- ============================= begin COMISR.ASM =======================
- DGRP GROUP DSEG,BSEG
- DSEG SEGMENT BYTE PUBLIC 'IDATA'
- DSEG ENDS
- BSEG SEGMENT BYTE PUBLIC 'UDATA'
- BSEG ENDS
- CSEG SEGMENT BYTE PUBLIC 'CODE'
- ASSUME CS:CSEG, DS:DGRP, SS:DGRP
- EXTRN ?eq:NEAR,?ne:NEAR,?lt:NEAR,?le:NEAR,?gt:NEAR
- EXTRN ?ge:NEAR,?ult:NEAR,?ule:NEAR,?ugt:NEAR,?uge:NEAR
- EXTRN ?not:NEAR,?switch:NEAR,?temp:WORD
- INCLUDE ISR.INC
- PUBLIC _isr_off
- _isr_off: PUSH BP
- MOV BP,SP
- mov AX, OFFSET _isr
- POP BP
- RET
- PUBLIC _isr_seg
- _isr_seg: PUSH BP
- MOV BP,SP
- mov AX, SEG _isr
- POP BP
- RET
- _isr: ISR_PROLOG
- SUB SP,1
- MOV AX,1
- MOV DGRP:_tempflag,AX
- MOV AX,33
- PUSH AX
- CALL _in
- ADD SP,2
- MOV -1[BP],AL
- MOV AX,33
- PUSH AX
- MOV AL,DGRP:_pic_mask
- NOT AL
- OR AL,-1[BP]
- XOR AH,AH
- PUSH AX
- CALL _out
- ADD SP,4
- MOV AX,32
- PUSH AX
- MOV AX,32
- PUSH AX
- CALL _out
- ADD SP,4
- MOV AX,DGRP:_g_com
- ADD AX,2
- PUSH AX
- CALL _in
- ADD SP,2
- MOV -1[BP],AL
- ?1:
- MOV AL,-1[BP]
- AND AL,1
- JZ ??1
- JMP ?2
- ??1:
- MOV AL,-1[BP]
- AND AL,14
- XOR AH,AH
- MOV CL,1
- SHR AX,CL
- MOV BX,OFFSET ?4
- JMP ?switch
- ?5:
- MOV AX,DGRP:_g_com
- ADD AX,5
- PUSH AX
- CALL _in
- ADD SP,2
- JMP ?3
- ?6:
- MOV AX,DGRP:_g_in_end
- INC AX
- MOV DGRP:_g_in_end,AX
- MOV CX,AX
- MOV AX,4095
- CALL ?gt
- JNZ ??2
- JMP ?7
- ??2:
- MOV AX,-1
- MOV DGRP:_g_in_end,AX
- ?7:
- MOV AX,DGRP:_g_in_end
- INC AX
- MOV DGRP:_g_in_end,AX
- DEC AX
- MOV AX,DGRP:_g_in_end
- MOV SI,OFFSET DGRP:_g_serial_in
- ADD SI,AX
- PUSH SI
- MOV AX,DGRP:_g_com
- PUSH AX
- CALL _in
- ADD SP,2
- POP BX
- MOV [BX],AL
- JMP ?3
- ?8:
- MOV AX,DGRP:_g_com
- PUSH AX
- CALL _in
- ADD SP,2
- JMP ?3
- ?9:
- MOV AX,DGRP:_g_out_beg
- MOV CX,DGRP:_g_out_end
- CALL ?ne
- JNZ ??3
- JMP ?10
- ??3:
- MOV AX,DGRP:_g_out_beg
- INC AX
- MOV DGRP:_g_out_beg,AX
- MOV CX,AX
- MOV AX,4095
- CALL ?gt
- JNZ ??4
- JMP ?11
- ??4:
- MOV AX,-1
- MOV DGRP:_g_out_beg,AX
- ?11:
- MOV AX,DGRP:_g_out_beg
- INC AX
- MOV DGRP:_g_out_beg,AX
- DEC AX
- MOV AX,DGRP:_g_com
- PUSH AX
- MOV AX,DGRP:_g_out_beg
- MOV SI,OFFSET DGRP:_g_serial_out
- ADD SI,AX
- MOV AL,[SI]
- CBW
- PUSH AX
- CALL _out
- ADD SP,4
- MOV AX,DGRP:_g_out_beg
- MOV CX,DGRP:_g_out_end
- CALL ?ne
- JNZ ??5
- JMP ?12
- ??5:
- MOV AX,1
- MOV DGRP:_ok2send,AX
- JMP ?13
- ?12:
- MOV AX,0
- MOV DGRP:_ok2send,AX
- ?13:
- JMP ?14
- ?10:
- MOV AX,1
- MOV DGRP:_ok2send,AX
- ?14:
- JMP ?3
- ?15:
- MOV AX,DGRP:_g_com
- ADD AX,6
- PUSH AX
- CALL _in
- ADD SP,2
- JMP ?3
- ?4:
- DW ?15,0,?9,1,?8,6,?6,2,?5,3,0
- DW ?3
- ?3:
- JMP ?1
- ?2:
- MOV AX,33
- PUSH AX
- CALL _in
- ADD SP,2
- MOV -1[BP],AL
- MOV AX,33
- PUSH AX
- MOV AL,-1[BP]
- AND AL,DGRP:_pic_mask
- XOR AH,AH
- PUSH AX
- CALL _out
- ADD SP,4
- add sp,1
- ISR_EPILOG
- CSEG ENDS
- EXTRN _tempflag:WORD
- EXTRN _pic_mask:BYTE
- EXTRN _g_out_end:WORD
- EXTRN _g_in_end:WORD
- EXTRN _g_out_beg:WORD
- EXTRN _ok2send:WORD
- EXTRN _g_com:WORD
- EXTRN _g_serial_in:BYTE
- EXTRN _g_serial_out:BYTE
- EXTRN _in:NEAR
- EXTRN _out:NEAR
- END
- ============================ end COMISR.ASM =======================
- ============================ begin COMISR.C ========================
- #include <stdio.h>
- #include "com.h"
-
- extern int tempflag;
-
- extern unsigned char pic_mask;
- extern int OUTEND, INEND, OUTST, OUTEND, ok2send;
- extern int g_com;
- extern char BUFIN[BUFSIZE], BUFOUT[BUFSIZE];
-
- unsigned int isr_off()
- {
- asm " mov AX, OFFSET _isr";
- }
-
- unsigned int isr_seg()
- {
- asm " mov AX, SEG _isr";
- }
-
- isr()
- {
- unsigned char pic;
-
- /* PROLOG, save registers, disable interrupts */
- asm " ISR_PROLOG";
-
- tempflag = 1;
- /* tell the PIC that int is being serviced */
- pic = in(0x21);
- out(0x21, pic | (~pic_mask));
- out(0x20, 0x20);
-
- /* check UART to see if it did the interrupt */
- pic = in(g_com + 2);
-
- /* service the interupt */
- while(!(pic & 1)) /* while interrupt caused by UART */
- {
- switch((pic & 14) >> 1) /* isolate bits 3, 2, and 1 */
- {
- case 3: /* error condition caused int */
- in(g_com + 5); /* read LSR to reset uart */
- break;
-
- case 2: /* RBF full (char ready) caused int */
- {
- if(++INEND > BUFSIZE - 1) /* wrap buffer index */
- INEND = -1;
-
- INEND++; /* "point" to THIS char */
-
- BUFIN[INEND] = in(g_com); /* add char to buffer */
- /* read RBR to reset uart */
-
- break;
- }
-
- case 6: /* FIFO stuff...ignore */
- in(g_com); /* read RBR, reset UART */
- break;
-
- case 1: /* THR empty...ready for new char, send next one */
- {
- if(OUTST != OUTEND) /* if buffer has something in it */
- {
- if(++OUTST > BUFSIZE - 1)
- OUTST = -1; /* wrap buffer index */
-
- OUTST++; /* point to first char */
-
- out(g_com, BUFOUT[OUTST]); /* send next char */
-
- if(OUTST != OUTEND) /* if buffer empty now */
- ok2send = 1;
- else
- ok2send = 0;
- }
- else
- ok2send = 1;
-
- break;
- }
-
- case 0: /* modem status change */
- in(g_com + 6);
- } /* end of switch */
- } /* end of while */
-
- /* tell the PIC that int is done being serviced */
- pic = in(0x21);
- out(0x21, pic & pic_mask);
-
- asm " ISR_EPILOG";
- }
- ============================ end COMISR.C =========================
-
- ==============================================
- From: Mike Dorman
- mikedorman@cedarnet.com
- 1:283/119.1012@fidonet
- http://www.cedarnet.com/bbs/users/mikedorman/
- ==============================================
-